# coding: utf-8

"""Train tickets query via command-line.

Usage:
   tickets [-gdtkz] <from> <to> <date>
   tickets -g 西安 北京 2019-03-12

Options:
   -h,--help   显示帮助菜单
   -g          高铁
   -d          动车
   -t          特快
   -k          快速
   -z          直达

Example:
   tickets 西安 北京 2019-03-12
   tickets -dg 成都 南京 2016-10-10
"""

import requests
import urllib3

urllib3.disable_warnings(urllib3.exceptions.InsecureRequestWarning)

from docopt import docopt
from stations import stationsByCode, stationsByName


# 禁用安全请求警告 python2 下
# from requests.packages.urllib3.exceptions import InsecureRequestWarning
# requests.packages.urllib3.disable_warnings(InsecureRequestWarning)


def cli():
    """ command - line interface """
    arguments = docopt(__doc__)
    # print(arguments)

    from_station = stationsByName.get(arguments['<from>'])
    to_station = stationsByName.get(arguments['<to>'])
    date = arguments['<date>']
    url = 'https://kyfw.12306.cn/otn/leftTicket/queryX?leftTicketDTO.train_date={}&leftTicketDTO.from_station={}&leftTicketDTO.to_station={}&purpose_codes=ADULT'.format(
        date, from_station, to_station)
    # print(url)
    r = requests.get(url, verify=False)
    # print(r.json())
    jsonobj = r.json()
    # print(jsonobj)

    if jsonobj['messages']:
        print(jsonobj['messages'])
    else:
        rows = jsonobj['data']['result']
        trains = TrainCollection(rows, arguments)
        trains.pretty_print()


from prettytable import PrettyTable
from colorama import init, Fore

init()


class TrainCollection(object):
    # header = 'train station_start station_end station_src station_des time_start time_end time tic dat gr rw rz wz yw yz edz ydz swz dw'.split()
    # 始发站 终到站
    # header = '车次 起始站 终点站 出发时间 到达时间 历时 是否有票 出发日期 高级软卧 软卧 软座 无座 硬卧 硬座 二等座 一等座 商务座 动卧'.split()
    header = ['车次', '车站', '时间', '历时', '商务座', '一等', '二等', '高级软卧', '软卧', '动卧', '硬卧', '软座', '硬座', '无座', '备注']

    # print(header)

    def __init__(self, rows, options):
        self.rows = rows
        self.options = options

    def _get_duration(self, row):
        """ 获取车次运行时间 """
        duration = row[10].replace(':', '小时') + '分'
        if duration.startswith('00'):
            return duration[4:]
        if duration.startswith('0'):
            return duration[1:]
        return duration

    @property
    def trains(self):
        for row in self.rows:
            # 循环遍历每辆列车的信息
            data_list = row.split('|')

            # 车次号码
            train_no = data_list[3]

            # '-d': False,
            # '-g': True,
            # '-k': False,
            # '-t': False,
            # '-z': False,
            checi = []
            if self.options['-d']:
                checi.append('D')
            if self.options['-g']:
                checi.append('G')
            if self.options['-k']:
                checi.append('K')
            if self.options['-t']:
                checi.append('t')
            if self.options['-z']:
                checi.append('Z')
            if len(checi) > 0:
                if not train_no[0:1] in checi:
                    continue

            # 始发站 train
            begin_station_code = data_list[4]
            begin_station_name = stationsByCode.get(begin_station_code)
            # 终到站 train
            end_station_code = data_list[5]
            end_station_name = stationsByCode.get(end_station_code)
            # 出发站 your
            from_station_code = data_list[6]
            from_station_name = stationsByCode.get(from_station_code)
            # 终点站 your
            to_station_code = data_list[7]
            to_station_name = stationsByCode.get(to_station_code)
            # 判断是起始还是经过
            begin_flag = self.__check_equals(begin_station_code, from_station_code, 1)
            end_flag = self.__check_equals(end_station_code, to_station_code, 2)

            # 出发时间
            start_time = data_list[8]
            # 到达时间
            arrive_time = data_list[9]
            # 总耗时
            # time_fucked_up = self._get_duration(data_list)
            time_fucked_up = data_list[10]

            train = [train_no,
                     '\n'.join([begin_flag + ' ' + self.__get_color(Fore.GREEN, from_station_name),
                                end_flag + ' ' + self.__get_color(Fore.RED, to_station_name)]),
                     '\n'.join([self.__get_color(Fore.GREEN, start_time),
                                self.__get_color(Fore.RED, arrive_time)]),
                     time_fucked_up,
                     # 历时
                     data_list[32],
                     # 特等座
                     self.__show_color(data_list[31]),
                     # 一等
                     self.__show_color(data_list[30]),
                     # 二等
                     self.__show_color(data_list[22]),
                     # 高级软卧
                     self.__show_color(data_list[23]),
                     # 软卧
                     self.__show_color(data_list[33]),
                     # 硬卧
                     self.__show_color(data_list[28]),
                     # 软座
                     self.__show_color(data_list[24]),
                     # 硬座
                     self.__show_color(data_list[29]),
                     # 无座
                     self.__show_color(data_list[26]),
                     # 备注
                     self.__show_color(data_list[1])
                     ]

            # 更改不运行车次的时间和历时
            if data_list[14] == 'null':
                train[2] = '--\n--'
                train[3] = '--'
            # 将空字符串转化为‘--’
            for i, item in enumerate(train):
                if not item:
                    train[i] = '--'

            yield train

    def __check_equals(self, from_station, to_station, type):
        """
        检查是否是始、过
            检查你的起始站是否为该车次的起始站
            检查你的终止站是否为该车次的终止站
        :param from_station:  出发位置
        :param to_station:     结束位置
        :return: 决定了是使用‘始' 还是 ’过‘
        """
        if from_station == to_station:
            return Fore.YELLOW + '始' + Fore.RESET if (type == 1) else Fore.LIGHTRED_EX + '终' + Fore.RESET
        else:
            return Fore.LIGHTBLUE_EX + '过' + Fore.RESET

    def __get_color(self, color, content):
        """
        返回颜色内容组合，并且清除该内容之后的颜色
        :param color: 传递的颜色
        :param content: 内容
        :return: 返回值为拼接上颜色
        """
        return color + content + Fore.RESET

    def __show_color(self, content):
        """
        对内容进行颜色显示，并且只显示有，其余不上色
        :param content: 需要颜色显示的内容
        :return: 返回设置结果
        """
        if content == '有':
            return Fore.GREEN + content + Fore.RESET
        else:
            return content

    def pretty_print(self):
        """ 数据已经获取到了，剩下的就是提取我们要的信息并将它显示出来。`prettytable`这个库可以让我们它像MySQL数据库那样格式化显示数据 """
        pt = PrettyTable()  # 设置每一列的标题
        pt._set_field_names(self.header)
        pt.align["车次"] = "r"
        pt.align["车站"] = "l"
        # pt.valign["车次"] = "t"
        # pt.hrules = 1 # 水平线
        # pt.set_style(20)
        index = 0
        for train in self.trains:
            pt.add_row(train)
            index = index + 1
        print(pt)
        print("| 总共",Fore.RED + str(index) + Fore.RESET,"趟车次 |")
        print("==================")


if __name__ == '__main__':
    cli()

# https://kyfw.12306.cn/otn/leftTicket/queryX?leftTicketDTO.train_date=2019-03-12&leftTicketDTO.from_station=XAY&leftTicketDTO.to_station=BJP&purpose_codes=ADULT
# https://kyfw.12306.cn/otn/resources/js/framework/station_name.js?station_version=1.9098
